home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / src / X11 / xmartin-2.2 / xmartin+.pl < prev   
Perl Script  |  1995-05-03  |  10KB  |  276 lines

  1. #! /usr/bin/perl
  2. #
  3. #   xmartin+ - front end to the xmartin root window decorator
  4. #
  5. #   xmartin+ [-q] [-demo] [-n name] [-f file] [-repeat [seconds]] [-save]
  6. #            [xmartin-options]
  7.  
  8. $File = "$ENV{'HOME'}/.xmartin+";
  9. $xmFile = "$ENV{'HOME'}/.xmartin";
  10. $xmNoArg ="^-(mono|nrc|v|rv|static)|\\+rv$";
  11. $xmArg = "^-(p|P|a|b|c|d|nc|zoom|move|coord|display)$";
  12. $xmOptArg = "^-(bg|dynam|tile|perturb)$";
  13.  
  14. #---parse arguments------------------------------------------------------------
  15.  
  16. while($_ = shift) {
  17.    if    (m!^-[nf]$!) { $n = shift; &usage unless $n; push(@Names,$n); }
  18.    elsif (m!^-file$!) { $File = shift; &usage unless $File; }
  19.    elsif (m!^-q$!) { $Query++; }
  20.    elsif (m!^-demo$!) { $Demo++; }
  21.    elsif (m!^-save$!) { $Save++; }
  22.    elsif (m!^-repeat$!) { 
  23.       $Repeat++;
  24.       $Sleep = ($ARGV[0] =~ /^\d+/) ? shift : 1;
  25.       }
  26.    else {
  27.       if    (m!$xmNoArg!)  { $xmOpts .= "$_ "; }
  28.       elsif (m!$xmArg!)    { $xmOpts .= "$_ " . shift . ' '; }
  29.       elsif (m!$xmOptArg!) {
  30.      $xmOpts .= "$_ ";
  31.      if ($ARGV[0] !~ /^[-+]/ ) { $xmOpts .= shift . ' '; }
  32.      }
  33.       else { &usage; }
  34.       }
  35.    }
  36.  
  37. &initfile unless -s $File;
  38.  
  39. #---read file, concatenate continuation lines ---------------------------------
  40.  
  41. open(File, $File) || die "xmartin+: can't open $File: $!\n";
  42. while(<File>) { $text .= $_; }
  43. $* = 1; $text =~ s/\\\s*\n//g; @Lines = split(/\n/, $text); $* = 0;
  44.  
  45. #---parse file, extract entries------------------------------------------------
  46.  
  47. for(@Lines) {
  48.    $line = $_;
  49.    #---trim/skip comments
  50.    s/#.*$//; next if m!^\s*$!;
  51.    #---remove extraneous white space
  52.    s/^\s+//; s/\s+$//; s/\s+(:)/$1/g; s/(:)\s+/$1/g; s/\s+/ /g;
  53.    #---check syntax
  54.    m!^\S+:.*:\d+\.?\d*:\S! || die "xmartin+: invalid entry in $File:\n$line\n";
  55.    #---extract and record fields
  56.    m!([^:]*):([^:]*):([^:]*):(.*)!;
  57.    $name = $1; $comment = $2; $weight = $3; $parms = $4;
  58.    if ($name =~ /sv(\d+)/) {
  59.       $Svsqn = $1 unless $Svsqn > $1;
  60.       }
  61.    $Sum_weight += $weight;
  62.    $Comment{$name} = $comment;
  63.    $Weight{$name} = $weight;
  64.    #---check if reference to previous entry
  65.    if ($parms =~ /{(.*)}/ ) {
  66.       $pname = $1; $pname =~ s/\s//g;
  67.       if (!$Parms{$pname}) {
  68.      warn "xmartin+: no previous entry {$pname} for this line:\n";
  69.      die "$line\n";
  70.      }
  71.       $parms =~ s/{.*}/$Parms{$pname}/;
  72.       }
  73.    $Parms{$name} = $parms;
  74.    }
  75.  
  76. #---If save, save ~/.xmartin parms as entry in xmartin+ tailoring file-------
  77.  
  78. if ($Save) {
  79.    -s $xmFile || die "xmartin+: $xmFile empty or non-existent\n";
  80.    open(xmFile, $xmFile) || die "xmartin+: can't open $xmFile:$!\n";
  81.    while(<xmFile>) { chop; $savetext .= " $_"; }
  82.    $Svsqn++;
  83.    while (!$Svname) {
  84.       print "Enter name for save entry[sv$Svsqn]:";
  85.       $Svname = <>; chop $Svname;
  86.       if (!length($Svname)) { $Svname = "sv$Svsqn"; last; }
  87.       if ($Svname !~ /^[A-Za-z0-9_]+$/) {
  88.      warn "xmartin+: '$Svname' is not a valid save name.\n";
  89.      undef $Svname; next;
  90.      }
  91.       if ($Parms{$Svname}) {
  92.      warn "xmartin+: '$Svname' entry already exists!\n";
  93.      undef $Svname; next;
  94.      }
  95.       }
  96.    print "Enter brief comment for save entry[none]:";
  97.    $Svcom = <>; chop $Svcom;
  98.  
  99.    open(File, ">$File") || die "xmartin+: can't open $File for writing:$!\n";
  100.    print File $text;
  101.    print File "$Svname:$Svcom:0:$savetext\n";
  102.    close(File);
  103.    exit(0);
  104.    }
  105.  
  106.  
  107. #---If query, print out names-weights-comments and exit----------------------
  108.  
  109. if ($Query) {
  110. format top =
  111. Name----------  Weight Comment---------------------------------------------
  112. .
  113. format STDOUT =
  114. @<<<<<<<<<<<<<  @>>>>> @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  115. $_,              $weight, $Comment{$_}
  116. .
  117.    for (sort keys(%Weight)) { $weight = $Weight{$_} ? $Weight{$_} : ''; write; }
  118.    exit(0);
  119.    }
  120.  
  121. #---If demo, set to execute each entry once------------------------------------
  122.  
  123. if ($Demo) { for (sort keys(%Parms)) { push(@Names, $_); } }
  124.  
  125. #---if specific entries not requested, select one randomly---------------------
  126.  
  127. if ($#Names < 0) { srand(); &random;  }
  128.  
  129. #---generate/execute xmartin call(s)--------------------------------------------
  130.  
  131. for $n(@Names) {
  132.    $Parms{$n} || die qq|xmartin+: No entry found in $File for "-n $n"\n|;
  133.    }
  134.  
  135. while(1) {
  136.    for $n(@Names) {
  137.       print "xmartin+" . '=' x 60 . "\n";
  138.  
  139.       print "xmartin+ $n $Comment{$n}\n";
  140.       print "xmartin+ $Parms{$n}\n";
  141.       $xmOpts && print "xmartin+ $xmOpts\n";
  142.  
  143.       $cmd = "xmartin $Parms{$n} $xmOpts";
  144.       if (!fork) { exec($cmd); }  # system($cmd) masks ^C interrupts
  145.       wait;
  146.  
  147.       $Repeat && sleep($Sleep);
  148.       }
  149.  
  150.    last unless $Repeat;
  151.    &random if $Random;
  152.    }
  153.  
  154. #---initfile - set up default .xmartin+ file-----------------------------------
  155.  
  156. sub initfile {
  157.    warn "xmartin+: Setting up default xmartin+ file in $File\n";
  158.    warn "xmartin+: You may want to read the comments in this file.\n";
  159.    open (File, ">$File") || die "xmartin+: can't open $File:$!\n";
  160.    print File <<EOF;
  161. #
  162. #  xmartin+ tailoring file
  163. #
  164. #  Entries in this file are used by the xmartin+ front end to generate an
  165. #  xmartin call tailored to suit your preferences. Entry format:
  166. #
  167. #     <name>:<comment>:<weight>:<xmartin-parms>
  168. #
  169. #     <name> : a name for the entry. Used in "xmartin+ -n name".
  170. #
  171. #     <comment>: a brief comment describing the entry
  172. #
  173. #     <weight> : any positive numerical value. The weight divided by the 
  174. #                sum of the weights for all entries is the probability 
  175. #                that xmartin+ will select this entry. A weight of 0 can
  176. #                be used to record interesting parameters for recall by
  177. #                name.
  178. #
  179. #     <xmartin-parms> : the xmartin parameters for this entry. You can
  180. #                       include the parameters of a previously defined
  181. #                       entry by placing the name of the entry in braces
  182. #                       "{}" in the parms field of a subsequent entry.
  183. #            
  184. #  The default file has entries matching the random parameters used by 
  185. #  xmartin itself. Except "-tile" is used for the smallish martin2 patterns.
  186. #  The xmartin abc defaults for ejk2 and ab defaults for cp1 cannot be 
  187. #  expressed as linear, orthogonal ranges, so their setting is left to
  188. #  xmartin itself.
  189. #
  190.  
  191. martin1 :(square root): 33 : -f martin1 -a 40::1540  -b 3::20  -c  100::3100 
  192. martin2 :(sine)       :  2 : -f martin2 -a  3.0715927::3.2115927 -tile
  193. ejk1    :(linear)     :  8 : -f ejk1 -a -500:500 -b -0.4:+0.4 -c 10::110
  194. ejk2    :(log)        :  3 : -f ejk2  #can't do xmartin non-linear abc defaults
  195. ejk3    :(sine)       :  6 : -f ejk3 -a -500:500 -b .05::.40 -c 30::110
  196. ejk4    :(sine-sqrt hybrid): 6:\\
  197.      -f ejk4 -a -1000:1000 -b 1::10 -c 30:70 -zoom 0.7
  198. ejk5    :(sine-linear hybrid): 6:\\
  199.      -f ejk5 -a -600:600 -b .1::.4  -c 20::110 -zoom 0.7
  200. ejk6    :(arc sine):  6 : -f ejk6 -a 550:650 -b .5::1.5 -zoom 1.2 -move 320,500
  201.  
  202. rr1  :(Recuerdo power):  6 : -f rr1 -a 0::100 -b 0::20 -c 0::200 -d 0:.9
  203. cp1  :(Pickover sine) : 25 : -f cp1
  204.  
  205. jigsaw    :(perturbed martin2): 0 : -f martin2 -perturb 100,100
  206. canvas    :(perturbed martin2): 0 : -f martin2 -perturb 20,80
  207. flag      :(perturbed martin2): 0 : -f martin2 -perturb 100,1 -zoom 80
  208. angelhair :(perturbed martin2): 0 :\\
  209.        -f martin2 -perturb 5,1.6 -zoom 120 -move 140,250 -a -3.07:-3.18
  210. debris    :(perturbed martin2): 0 : {angelhair} -a -3.20:-3.25
  211.  
  212. 4lobe     :(ejk1 subset): 0 : -f ejk1 -a 205:215 -b 0.39:0.40 -c 35:45
  213. nucleus   :(ejk1 subset): 0 : -f ejk1 -a -30:-50 -b -.13:-.14 -c 50::70
  214. shards    :(ejk1 subset): 0 : -f ejk1 -a 125:130 -b 1 -c 60:70 -zoom 0.2
  215. peacock   :(ejk1 subset): 0 : -f ejk1 -a 125:128 -b 1.05 -c 60:65 -zoom 0.2
  216. neuron    :(ejk1 subset): 0 :\\
  217.        -f ejk1 -a 130:140 -b -1.1  -c -55:-65 -zoom 0.1 -nc 2000 -P 250000
  218. propeller :(ejk1 subset): 0 :\\
  219.        -f ejk1 -a 175:185 -b -0.28:-0.31 -c -40:-50 -zoom 0.2
  220. dragonfly :(ejk1 subset): 0 :\\
  221.            -f ejk1 -a 400:500 -b 1.4:1.5  -c -40:-60 -zoom 0.02 -move ne,200
  222. butterfly :(ejk1 subset): 0 :\\
  223.            -f ejk1 -a 140:200 -b .69:.70 -c -190:-200 -zoom 0.04 -p 100000
  224. parkayfly :(ejk1 subset): 0 : {butterfly} -perturb 
  225.  
  226. nova      :(polar ejk6): 0 : -f ejk6 -coord ra -move 0,0 -P 100000
  227.  
  228. #-----entries saved with "xmartin+ -save" after this line---------------------
  229. fission:(save example):0: -f ejk1 -zoom 1.00000000000000000e+00 -a -4.4195582241184226e+01 -b 1.62878468936082850e-01 -c 5.92603781619302480e+01 -x 0.00000000000000000e+00 -y 0.00000000000000000e+00 -perturb 1218,2.09941657103072770e+02
  230. fusion:(save example):0: -f ejk1 -zoom 1.00000000000000000e+00 -a 4.44351629250406570e+02 -b 7.12978960411583960e-02 -c -9.3767407916053031e+01 -x 0.00000000000000000e+00 -y 0.00000000000000000e+00 -perturb 9737,8.39145051045554060e+02
  231. rocketeer:(Dan Lovinger):0: -f cp1,7,5436,5307 -zoom 1.25000000000000000e+02 -a 1.85005116080874790e+01 -b 6.16683720269582650e+00 -x 2.00000000000000000e+01 -y 3.00000000000000000e+01 -move 310,320 -coord xy
  232. EOF
  233.    exit(0);
  234.    }
  235.  
  236. #---random - select an entry at random-----------------------------------------
  237.  
  238. sub random {
  239.    local($sum_weight) = 0;
  240.    $Sum_weight > 0 || die "xmartin+: no $File entries with non-zero weight\n";
  241.    $#Names = -1;
  242.    $Random = rand($Sum_weight);
  243.    for(keys %Weight) {
  244.       $weight = $Weight{$_};
  245.       next unless $weight > 0;
  246.       $sum_weight += $weight;
  247.       next if $sum_weight < $Random;
  248.       push(@Names, $_); last;
  249.       }
  250.    }
  251.  
  252. #---usage - explain usage & exit-----------------------------------------------
  253.  
  254. sub usage { 
  255.    print STDERR <<EOF;
  256. usage: xmartin+
  257.  
  258. [-q] [-n name] [-demo] [-repeat [secs]] [-save] [-file file] [xmartin-opts] 
  259.  
  260.    -q:      prints table of entry names, weights, & comments
  261.    -n name: add named entry to list of patterns to generate (also -f name)
  262.    -demo:   executes every entry once
  263.    -repeat: repeats patterns indefinitely (until ^C). If present "secs" is
  264.         time to sleep between patterns.
  265.    -save:   save the exact hopalong parameters for the previous pattern as an
  266.         entry in the xmartin+ tailoring file so it can be recalled later 
  267.         with "xmartin+ -n name". You will be prompted for the name to use 
  268.         (default: svnn) and a brief comment to include in the entry.
  269.    -file file: use a file other than ~/.xmartin+
  270.  
  271.    xmartin-opts: xmartin(1) options (except -recall) to add to or alter 
  272.          those generated by xmartin+
  273. EOF
  274.    exit(1);
  275.    }
  276.